/**
 * @Description: 不同类型的模型提供加载器
 * @Author: Darren_yan
 * @Date: 2025-06-25 14:09:52
 * @LastEditors: Darren_yan
 * @LastEditTime: 2025-06-25 13:45:52
 */
import { isExist } from '../tools/index.js'
import { globeCollection } from './map_collection.js'
import { flyTo, flyToEntityById } from './map_camera.js'
//创建Tileset模型
function createTileset(
	{
		id,
		url,
		headerLists,
		maximumMemoryUsage,
		skipLevelOfRenderable,
		genMeshNormals,
		geometricErrorScale,
		skipLevelOfDetail,
		clipLevelOfDetail,
		streamingMode,
		geometryRenderer,
		modelStyle,
		flyOption,
		voluntarilyFly,
		memoryUsageUnit,
		compatible,
		name,
		modelTransform
	},
	cb
) {
	if (!isExist(id)) {
		console.error('id 错误')
		return
	}

	if (!isExist(url)) {
		console.error('url 错误')
		return
	}

	if (isExist(globeCollection.tileset[id])) {
		console.error('id Tileset已存在')
		return
	}

	const tileset = new SSmap.Tileset()
	tileset.dataType = 'Tileset'
	if (isExist(headerLists) && (typeof headerLists) === "object") {
		headerLists.forEach(item => {
			tileset.setHeader(item.key, item.value)
		});		
	}
	if (isExist(maximumMemoryUsage)) {
		let MemoryUsagenum = maximumMemoryUsage
		if(memoryUsageUnit === "GB"){
       MemoryUsagenum = maximumMemoryUsage * 1024
		}else if(memoryUsageUnit === "KB"){
       MemoryUsagenum = maximumMemoryUsage / 1024
		}
		tileset.maximumMemoryUsage = MemoryUsagenum
	}

	if (isExist(skipLevelOfRenderable)) {
		tileset.skipLevelOfRenderable = skipLevelOfRenderable
	}

	if (isExist(genMeshNormals)) {
		tileset.genMeshNormals = genMeshNormals
	}

	if (isExist(geometricErrorScale)) {
		tileset.geometricErrorScale = geometricErrorScale
	}

	if (isExist(skipLevelOfDetail)) {
		tileset.skipLevelOfDetail = skipLevelOfDetail
	}
	if (isExist(clipLevelOfDetail)) {
		tileset.clipLevelOfDetail = clipLevelOfDetail
	}

	if (isExist(streamingMode)) {
		tileset.streamingMode = streamingMode
	}
	if (isExist(compatible)) {
		tileset.compatible = compatible
	}
	if (isExist(name)) {
		tileset.tag = name
	}	
	tileset.load(url)

	const entity = new SSmap.Entity()
	entity.addComponent(tileset)
	window.GlobalViewer.scene.addEntity(entity)
	if (!isExist(globeCollection.tileset[id])) {
		// throw new Error('id Tileset已存在')
		// 网页端 contentLoaded 回调会重复执行
		globeCollection.tileset[id] = tileset
	}
  //定位
	tileset.readyPromise.then(() => {
			if(isExist(flyOption) && !voluntarilyFly){
					flyTo(flyOption)
			}else if(voluntarilyFly){
					flyToEntityById({id,dataType:"Tileset"})
			}
      //加载完之后
			tileset.contentLoaded(() => {
				updateTilesetStyleById(
					{
						id,
						style:modelStyle,
						rotation:modelTransform.rotation,
						offset:modelTransform.offset,
					},
					null
				)
				if (typeof cb === 'function' && tileset.tag == 'test') {
					cb(tileset)
				}		
			})
	});
	
	
}
//根据id 显示隐藏Tileset模型
function setEnabledTilesetById({id,enabled}){
  if (!isExist(id)) {
		console.error('id 错误')
		return
	}
	if (!isExist(globeCollection.tileset[id])) {
		console.error('id Tileset不存在')
		return
	}
	const tileset = globeCollection.tileset[id]
	tileset.enabled = enabled
}

//根据id更新 Tileset模型样式 
function updateTilesetStyleById(
	{ id, style, rotation, offset, tag },
	cb
) {
	if (!isExist(id)) {
		console.error('id 错误')
		return
	}
	if (!isExist(globeCollection.tileset[id])) {
		console.error('id Tileset不存在')
		return
	}
	const tileset = globeCollection.tileset[id]

	if (isExist(style)) {
		const tilesetStyle = new SSmap.TilesetStyle()
		if (isExist(style.useOverrideMaterial))
			tilesetStyle.useOverrideMaterial = style.useOverrideMaterial
		if (isExist(style.roughness)) tilesetStyle.roughness = style.roughness
		if (isExist(style.metallic)) tilesetStyle.metallic = style.metallic
		if (isExist(style.saturation )) tilesetStyle.saturation  = style.saturation 
		if (isExist(style.contrast )) tilesetStyle.contrast  = style.contrast 
		if (isExist(style.brightness)) tilesetStyle.brightness = style.brightness
		if (isExist(style.gamma)) tilesetStyle.gamma  = style.gamma 
		tileset.style = tilesetStyle
	}

	let quaternion = SSmap.Quaternion.fromEulerAngles(0, 0, 0)
	if (isExist(rotation)) {
		quaternion = SSmap.Quaternion.fromEulerAngles(
			rotation.x,
			rotation.y,
			rotation.z
		)
	}

	let vector3 = SSmap.Vector3.create(0, 0, 0)
	if (isExist(offset)) {
		vector3 = SSmap.Vector3.create(offset.x, offset.y, offset.z)
	}

	const matrix3 = quaternion.toRotationMatrix()
	tileset.modelMatrix = SSmap.Matrix4.fromRotationTranslation(matrix3, vector3)

	tileset.entity.travalRenderers((renderer) => {
		if (!isExist(renderer)) throw new Error('renderer 错误')
		if (isExist(style)) {
			if (isExist(style.shadingModel)) {
				renderer.material.shadingModel =
					SSmap.ShadingModel[style.shadingModel]
			}

			if (isExist(style.color) && style.shadingModel === 'UserShader') {
				const { r, g, b, a } = style.color
				renderer.material.color = SSmap.Color.fromRgb(r, g, b, a)
				renderer.material.opacity = a
			}
		}
	})
	if (isExist(tag)) {
		tileset.tag = tag
	}
	if (typeof cb === 'function') cb()
}

//删除 Tileset 模型
function removeTilesetById(id){
  if (!isExist(id)) {
		console.error('id 错误')
		return
	}
	if (!isExist(globeCollection.tileset[id])) {
		console.error('id Tileset不存在')
		return
	}
	const tileset = globeCollection.tileset[id]
	if(tileset){
		tileset.delete()
		delete globeCollection.tileset[id]
	}
}

function createModel(
	{ id, url, srs, cartographic, modelTransform, modelStyle, colorByName, voluntarilyFly,flyOption },
	cb
) {
	if (!isExist(id)) {
		// throw new Error('id 错误')
		console.error('id 错误')
		return
	}

	if (!isExist(url)) {
		// throw new Error('url 错误')
		console.error('url 错误')
		return
	}

	if (isExist(globeCollection.models[id])) {
		// throw new Error('id Model 已存在')
		console.error('id Model 已存在')
		return
	}

	const model = new SSmap.Model(url)	
	const entity = new SSmap.Entity()
	//坐标
	if (isExist(srs)) {
		model.srs = srs
	}else if (isExist(cartographic)  &&
		isExist(cartographic.lng) &&
		isExist(cartographic.lat) &&
		isExist(cartographic.alt)) {
		entity.transform.cartographic = SSmap.Cartographic.fromDegrees(
			cartographic.lng,
			cartographic.lat,
			cartographic.alt
		)
	}
	entity.addComponent(model)
	window.viewer.scene.addEntity(entity)
	model.dataType = 'Model'
	globeCollection.models[id] = model
	model.readyPromise.then(() => {
		if(isExist(flyOption) && !voluntarilyFly){
			flyTo(flyOption)
		}else if(voluntarilyFly){
			flyToEntityById({id,dataType:"Model"})
		}
		let {rotation,offset,scale} = modelTransform
		updateModelById(
			{ id, rotation,offset,scale, style:modelStyle,  colorByName },
			null
		)
		if (typeof cb === 'function') cb()
	})
}

function updateModelById(
	{ id, cartographic,srs, style, rotation,offset,scale, colorByName },
	cb
) {
	if (!isExist(id)) {
		// throw new Error('id 错误')
		console.error('iid 错误')
		return
	}

	if (!isExist(globeCollection.models[id])) {
		// throw new Error('id Model不存在')
		console.error('id Model 已存在')
		return

	}

	const model = globeCollection.models[id]
	if(!isExist(srs)){
        if (isExist(cartographic)  &&
			isExist(cartographic.lng) &&
			isExist(cartographic.lat) &&
			isExist(cartographic.alt)) {
			model.entity.transform.cartographic = SSmap.Cartographic.fromDegrees(
				cartographic.lng,
				cartographic.lat,
				cartographic.alt
			)
		}
	}

	// let {rotation,offset,scale} = modelTransform
	
	if (
		isExist(rotation) &&
		isExist(rotation.x) &&
		isExist(rotation.y) &&
		isExist(rotation.z)
	) {
		model.rotation = SSmap.Quaternion.fromEulerAngles(
			rotation.x,
			rotation.y,
			rotation.z
		)
	}

	if (isExist(offset) && isExist(offset.x) && isExist(offset.y) && isExist(offset.z)) {
		model.offset = SSmap.Vector3.create(offset.x, offset.y, offset.z)
	}

	if (isExist(scale) && isExist(scale.x) && isExist(scale.y) && isExist(scale.z)) {
		model.scale = SSmap.Vector3.create(scale.x, scale.y, scale.z)
	}
	model.parent.travalRenderers((renderer) => {
		if (!isExist(renderer)) {
			// throw new Error('renderer 错误')
			console.error('renderer 错误')
		    return
		}
		if (isExist(style)) {
			// 设置渲染材质包含Shader、渲染状态、参数
			// 设置着色模式
			if (isExist(style.shadingModel)) {
				renderer.material.shadingModel =
					SSmap.ShadingModel[style.shadingModel]
			}

			if (isExist(style.opacity)) {
				renderer.material.opacity = style.opacity
			}

			if (isExist(style.transparent)) {
				renderer.material.transparent = style.transparent
			}
			// 设置颜色
			if (
				isExist(style.color) &&
				isExist(style.color.r) &&
				isExist(style.color.g) &&
				isExist(style.color.b) &&
				isExist(style.color.a) &&
				style.shadingModel === "UserShader"
			) {
				const { r, g, b, a } = style.color
				renderer.material.color = SSmap.Color.fromRgb(r, g, b, a)
			}
			// 设置水体参数
			if (isExist(style.waterParameters) && style.shadingModel === "Water") {
				// 材质中的水体参数控制对象 设置波浪角度
				if (isExist(style.waterParameters.flowAngle)) {
					renderer.material.waterParameters().flowAngle = style.waterParameters.flowAngle
				}

				// 材质中的水体参数控制对象 设置波浪速度
				if (isExist(style.waterParameters.flowSpeed)) {
					renderer.material.waterParameters().flowSpeed = style.waterParameters.flowSpeed
				}

				// 材质中的水体参数控制对象 设置凹凸平铺数量
				if (isExist(style.waterParameters.bumpTilling)) {
					renderer.material.waterParameters().bumpTilling = style.waterParameters.bumpTilling
				}

				// 材质中的水体参数控制对象 设置水体反射颜色系数
				if (isExist(style.waterParameters.specularFactor)) {
					renderer.material.waterParameters().specularFactor = style.waterParameters.specularFactor
				}
			}

			// 设置是否投射阴影
			if (isExist(style.castShadow)) {
				renderer.castShadow = style.castShadow
			}

			// 设置是否接受阴影
			if (isExist(style.receiveShadow)) {
				renderer.receiveShadow = style.receiveShadow
			}
		}

		if (isExist(colorByName) && Array.isArray(colorByName)) {
			colorByName.forEach((item) => {
				const objectName = renderer.entity.objectName
				if (objectName.includes(item.name) && isExist(item.name)) {
					renderer.material.color = SSmap.Color.fromRgb(
						item.color.r,
						item.color.g,
						item.color.b,
						item.color.a
					)
					renderer.material.opacity = item.color.a / 255
				}
			})
		}
	})

	if (typeof cb === 'function') cb()
}

//根据id 显示隐藏Model模型
function setEnabledModelById({id,enabled}){
  if (!isExist(id)) {
		console.error('id 错误')
		return
	}
	if (!isExist(globeCollection.models[id])) {
		console.error('id Model不存在')
		return
	}
	const model = globeCollection.models[id]
    if(isExist(model.entity)) model.entity.enabled = enabled
}

function removeModelById(id, cb) {
	if (!isExist(id)) {
		// throw new Error('id 错误')
		console.error('id 错误')
		return
	}

	if (!isExist(globeCollection.models[id])) {
		// throw new Error('id Model不存在')
	    console.error('id Model 已存在')
		return
	}

	const model = globeCollection.models[id]
	model.entity.delete()
	delete globeCollection.models[id]
	if (typeof cb === 'function') cb()
}

export {createTileset,updateTilesetStyleById,setEnabledTilesetById,removeTilesetById,
	   createModel, updateModelById, setEnabledModelById, removeModelById
}